# AdvDS.pl - Advanced Data Structures

#!/usr/bin/perl

use strict;
use warnings;

# data member declaration
my ($line,
	$variable_ref,
	@arr,
	$array_ref,
	%stuff,
	$hash_ref,
	$i,
	$j,
	@AOA,
	@temp_arr,
	%HOA,
	@AOH,
	$key,
	$value,
	%HOH,
	$mkey
	);
	
print "\n";
print "--------------------------\n";
print "Advanced Data Structures\n";
print "--------------------------\n";

# <HARD-REFERENCES>

# variable reference
$line = "This is a referenced string.\n";
$variable_ref = \$line;

print "${$variable_ref}";

# array reference
for($i = 0; $i < 3; $i++) {
	$arr[$i] = "Element ".($i + 1);
}

$array_ref = \@arr;
print "\n";

for($i = 0; $i < 3; $i++) {
	print "arr[$i]: ${$array_ref}[$i]\n";
}

# Hash reference
%stuff = (
	"Ark" => 1,
	"Brk" => 2,
	"Crk" => 3
	);

$hash_ref = \%stuff;
$hash_ref->{"Drk"} = 14;
print "\n";

print "$hash_ref->{'Ark'}\n"; # same as ${$hash_ref}{'Ark'} or $$hash_ref{'Ark'}
print "$hash_ref->{'Brk'}\n";
print "$hash_ref->{'Crk'}\n";
print "$hash_ref->{'Drk'}\n";

# </HARD-REFERENCES>

# arrays of arrays
@AOA = ([1, "Claudio", 45], [2, "Redwan", 145], [3, "Robin", 236]);

print "\n";
print "--------\n";
print "Pass 1\n";
print "--------\n";

for($i = 0; $i <= $#AOA; $i++) {
	for($j = 0; $j <= $#{$AOA[$i]}; $j++) {
		print "$AOA[$i][$j]\t";
	}
	
	print "\n";
}

print "\n";

@temp_arr = (4, "John", 882);
# add a row
push(@AOA, [@temp_arr]);

print "--------\n";
print "Pass 2\n";
print "--------\n";

for($i = 0; $i <= $#AOA; $i++) {
	for($j = 0; $j <= $#{$AOA[$i]}; $j++) {
		print "$AOA[$i][$j]\t";
	}
	
	print "\n";
}

print "\n";

for($i = 0; $i <= $#AOA; $i++) {
	push(@{$AOA[$i]}, "new_value");
}

print "--------\n";
print "Pass 3\n";
print "--------\n";

for($i = 0; $i <= $#AOA; $i++) {
	for($j = 0; $j <= $#{$AOA[$i]}; $j++) {
		print "$AOA[$i][$j]\t";
	}
	
	print "\n";
}

print "\n";
# print @AOA;

# hashes of arrays
%HOA = (
	"Numbers" => [1,2,3],
	"Names" => ["Morpheus", "Neo", "Smith"]
	);
	
@temp_arr = ("Arr", "Grr", "Gastby");
# add an array to hash
$HOA{'new_key'} = [@temp_arr];
# add a column to one of the arrays
push(@{$HOA{"new_key"}}, 'some_value');

print "$HOA{'Numbers'}->[2]\n";
print "$HOA{'Names'}->[2]\n";
print "$HOA{'new_key'}->[2]\n";
print "$HOA{'new_key'}->[3]\n";

print "\n";

# arrays of hashes
@AOH = (
	{"key11" => "value11", "key12" => "value12"},
	{"key21" => "value21", "key22" => "value 22"}
	);

# add a hash to array
push(@AOH, {"key31" => "value31", "key32" => "value32"});

# add a key/value pair in one of hashes
$AOH[2]{"key33"} = "value33";

for($i = 0; $i <= $#AOH; $i++) {
	while(($key, $value) = each(%{$AOH[$i]})) {
		print "Key: $key\n";
		print "Value: $value\n";
	}
}

print "\n";

# hashes of hashes
%HOH = (
	"Masterkey1" => {"Subkey11" => "Value11", "Subkey12" => "Value12"},
	"Masterkey2" => {"Subkey21" => "Value21", "Subkey22" => "Value22"}
	);
	
$HOH{"Masterkey3"} = {"Subkey31" => "Value31", "Subkey12" => "Value32"};
$HOH{"Masterkey3"}{"Subkey33"} = "Value33";

while(($mkey) = each(%HOH)) {
	print "Masterkey: $mkey\n";
	
	while(($key, $value) = each(%{$HOH{$mkey}})) {
		print "Key: $key\n";
		print "Value: $value\n";
	}
	
	print "\n";
}